<template>
  <div id="map">
    <div id="deviceInfo" class="deviceInfo">
      <div class="titleBox wp100 h48">
        <span class="title fs15 h48 lh48 w31 wp100">详情</span>
      </div>
      <div class="infoBox h34 wp100 flr mt8">
        <span class="titleLabel fs14 lh34 h34">项目名称：</span>
        <span class="titleContent fs14 lh34 h34">{{ curDeviceInfo.name }}</span>
      </div>
      <div class="infoBox h34 wp100 flr mt8">
        <span class="titleLabel fs14 lh34 h34">维保单位：</span>
        <span class="titleContent fs14 lh34 h34">{{ curDeviceInfo.maintenance }}</span>
      </div>
      <div class="infoBox h34 wp100 flr mt8">
        <span class="titleLabel fs14 lh34 h34">项目类型：</span>
        <span class="titleContent fs14 lh34 h34">{{ curDeviceInfo.type }}</span>
      </div>
      <div class="infoBox h34 wp100 flr mt8">
        <span class="titleLabel fs14 lh34 h34">项目地址：</span>
        <span class="titleContent fs14 lh34 h34">{{ curDeviceInfo.address }}</span>
      </div>
      <div class="infoBox h34 wp100 flr mt8">
        <span class="titleLabel fs14 lh34 h34">联系人：</span>
        <span class="titleContent fs14 lh34 h34">{{ curDeviceInfo.contacts }}</span>
      </div>
    </div>
  </div>
</template>
<script>
import 'ol/ol.css';
import { MAP_OPTIONS } from '@/config/mapConfig';
import { Feature, Map, View } from 'ol';
import { fromLonLat, toLonLat } from 'ol/proj';
import Tile from 'ol/layer/Tile';
import { get as getProj } from 'ol/proj';
import { getTopLeft, getWidth } from 'ol/extent';
import WMTS from 'ol/source/WMTS';
import WMTSTileGrid from 'ol/tilegrid/WMTS';
import Style from 'ol/style/Style';
import IconOl from 'ol/style/Icon';
import Text from 'ol/style/Text';
import Fill from 'ol/style/Fill';
import Point from 'ol/geom/Point';
import Vector from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import Overlay from 'ol/Overlay';
import Cluster from 'ol/source/Cluster';
import NomalIcon from '@/assets/image/map/normal.png';
import WarningIcon from '@/assets/image/map/warning.png';
import Cluster1 from '@/assets/image/map/cluster1.png';
import Cluster0 from '@/assets/image/map/cluster0.png';
export default {
  data() {
    return {
      curDeviceInfo: {},
      MAP_OPTIONS,
      showMapList: false,
      markListByArea: [],
      markListAll: [],
      map: null,
      gpsLongitude: '',
      gpsLatitude: '',
      deviceOverlay: null,
      curCoord: null,
      timer: null,
      curMapType: 'filter' //这里更具自己需求做下跟随用户选择记录/跟随电脑本地选择记录
    };
  },
  mounted() {
    this.gpsLongitude = 114.123456789; // 默认经度
    this.gpsLatitude = 32.2625412545; // 默认纬度
    this.markListByArea = [
      {
        layerName: 'jiangsu',
        lonlat: [
          { status: 'WARNING', longitude: 119.498723456, latitude: 32.971178901, name: '东大只能集团办公大楼11', maintenance: '维保单位', type: '项目类型', address: '南京xxxxxx', contacts: '张三1996666666' },
          { status: 'NORMAL', longitude: 120.558957122, latitude: 31.325152456, name: '东大只能集团办公大楼12', maintenance: '维保单位', type: '项目类型', address: '南京xxxxxx', contacts: '张三1996666666' },
          { status: 'WARNING', longitude: 118.79687512, latitude: 32.055423698, name: '东大只能集团办公大楼13', maintenance: '维保单位', type: '项目类型', address: '南京xxxxxx', contacts: '张三1996666666' },
          { status: 'NORMAL', longitude: 121.473621987, latitude: 31.230448563, name: '东大只能集团办公大楼14', maintenance: '维保单位', type: '项目类型', address: '南京xxxxxx', contacts: '张三1996666666' },
          { status: 'NORMAL', longitude: 118.281254321, latitude: 34.269721058, name: '东大只能集团办公大楼15', maintenance: '维保单位', type: '项目类型', address: '南京xxxxxx', contacts: '张三1996666666' },
          { status: 'WARNING', longitude: 119.914062741, latitude: 33.684021987, name: '东大只能集团办公大楼16', maintenance: '维保单位', type: '项目类型', address: '南京xxxxxx', contacts: '张三1996666666' },
          { status: 'NORMAL', longitude: 120.307128965, latitude: 31.394167258, name: '东大只能集团办公大楼17', maintenance: '维保单位', type: '项目类型', address: '南京xxxxxx', contacts: '张三1996666666' },
          { status: 'NORMAL', longitude: 119.632812574, latitude: 34.597222135, name: '东大只能集团办公大楼18', maintenance: '维保单位', type: '项目类型', address: '南京xxxxxx', contacts: '张三1996666666' },
          { status: 'NORMAL', longitude: 120.902343851, latitude: 31.798611204, name: '东大只能集团办公大楼19', maintenance: '维保单位', type: '项目类型', address: '南京xxxxxx', contacts: '张三1996666666' },
          { status: 'NORMAL', longitude: 118.80859375, latitude: 32.055423698, name: '东大只能集团办公大楼20', maintenance: '维保单位', type: '项目类型', address: '南京xxxxxx', contacts: '张三1996666666' }
        ]
      },
      {
        layerName: 'hubei',
        lonlat: [
          { status: 'WARNING', longitude: 114.183456789, latitude: 30.287654321, name: '武汉大学11', maintenance: '维保单位', type: '项目类型', address: '武汉xxxxxx', contacts: '张三1996666666' },
          { status: 'NORMAL', longitude: 110.456789012, latitude: 31.765432109, name: '武汉大学12', maintenance: '维保单位', type: '项目类型', address: '武汉xxxxxx', contacts: '张三1996666666' },
          { status: 'WARNING', longitude: 108.351111111, latitude: 29.081111111, name: '武汉大学13', maintenance: '维保单位', type: '项目类型', address: '武汉xxxxxx', contacts: '张三1996666666' },
          { status: 'NORMAL', longitude: 116.071111111, latitude: 33.331111111, name: '武汉大学14', maintenance: '维保单位', type: '项目类型', address: '武汉xxxxxx', contacts: '张三1996666666' },
          { status: 'NORMAL', longitude: 112.678901234, latitude: 32.456789012, name: '武汉大学15', maintenance: '维保单位', type: '项目类型', address: '武汉xxxxxx', contacts: '张三1996666666' },
          { status: 'WARNING', longitude: 115.55555555, latitude: 30.555555555, name: '武汉大学16', maintenance: '维保单位', type: '项目类型', address: '武汉xxxxxx', contacts: '张三1996666666' },
          { status: 'NORMAL', longitude: 109.23456789, latitude: 31.123456789, name: '武汉大学17', maintenance: '维保单位', type: '项目类型', address: '武汉xxxxxx', contacts: '张三1996666666' },
          { status: 'NORMAL', longitude: 113.765432109, latitude: 32.987654321, name: '武汉大学18', maintenance: '维保单位', type: '项目类型', address: '武汉xxxxxx', contacts: '张三1996666666' },
          { status: 'NORMAL', longitude: 111.012345678, latitude: 29.987654321, name: '武汉大学19', maintenance: '维保单位', type: '项目类型', address: '武汉xxxxxx', contacts: '张三1996666666' },
          { status: 'NORMAL', longitude: 114.901234567, latitude: 33.123456789, name: '武汉大学20', maintenance: '维保单位', type: '项目类型', address: '武汉xxxxxx', contacts: '张三1996666666' },
          { status: 'NORMAL', longitude: 114.123456789, latitude: 30.987654321, name: '武汉大学21', maintenance: '维保单位', type: '项目类型', address: '武汉xxxxxx', contacts: '张三1996666666' },
          { status: 'NORMAL', longitude: 115.555555555, latitude: 31.333333333, name: '武汉大学22', maintenance: '维保单位', type: '项目类型', address: '武汉xxxxxx', contacts: '张三1996666666' }
        ]
      }
    ];
    this.markListAll = [
      { status: 'WARNING', longitude: 119.498723456, latitude: 32.971178901, name: '东大只能集团办公大楼11', maintenance: '维保单位', type: '项目类型', address: '南京xxxxxx', contacts: '张三1996666666' },
      { status: 'NORMAL', longitude: 120.558957122, latitude: 31.325152456, name: '东大只能集团办公大楼12', maintenance: '维保单位', type: '项目类型', address: '南京xxxxxx', contacts: '张三1996666666' },
      { status: 'WARNING', longitude: 118.79687512, latitude: 32.055423698, name: '东大只能集团办公大楼13', maintenance: '维保单位', type: '项目类型', address: '南京xxxxxx', contacts: '张三1996666666' },
      { status: 'NORMAL', longitude: 121.473621987, latitude: 31.230448563, name: '东大只能集团办公大楼14', maintenance: '维保单位', type: '项目类型', address: '南京xxxxxx', contacts: '张三1996666666' },
      { status: 'NORMAL', longitude: 118.281254321, latitude: 34.269721058, name: '东大只能集团办公大楼15', maintenance: '维保单位', type: '项目类型', address: '南京xxxxxx', contacts: '张三1996666666' },
      { status: 'WARNING', longitude: 119.914062741, latitude: 33.684021987, name: '东大只能集团办公大楼16', maintenance: '维保单位', type: '项目类型', address: '南京xxxxxx', contacts: '张三1996666666' },
      { status: 'NORMAL', longitude: 120.307128965, latitude: 31.394167258, name: '东大只能集团办公大楼17', maintenance: '维保单位', type: '项目类型', address: '南京xxxxxx', contacts: '张三1996666666' },
      { status: 'NORMAL', longitude: 119.632812574, latitude: 34.597222135, name: '东大只能集团办公大楼18', maintenance: '维保单位', type: '项目类型', address: '南京xxxxxx', contacts: '张三1996666666' },
      { status: 'NORMAL', longitude: 120.902343851, latitude: 31.798611204, name: '东大只能集团办公大楼19', maintenance: '维保单位', type: '项目类型', address: '南京xxxxxx', contacts: '张三1996666666' },
      { status: 'NORMAL', longitude: 118.80859375, latitude: 32.055423698, name: '东大只能集团办公大楼20', maintenance: '维保单位', type: '项目类型', address: '南京xxxxxx', contacts: '张三1996666666' }
    ];
    this.initMap(); // 初始化地图
  },
  methods: {
    initMap() {
      this.map = new Map({ target: 'map', layers: [], view: new View({ center: fromLonLat([this.gpsLongitude, this.gpsLatitude]), zoom: 5 }) });
      this.addMapLayer(); //添加地图底图图层
      // this.addMarkByArea(this.markListByArea); //添加图标feature，按省聚合
      this.addMarkByAll(this.markListAll); //添加图标feature，
      this.addMapOverlay(); //添加地图遮罩框，弹框的一种
      this.map.on('click', this.mapClick); //添加地图点击事件
      this.map.on('pointermove', this.mapPointerMove); //添加地图鼠标移动事件
      this.map.on('postrender', this.mapPostrender); //添加地图缩放、拖拽等任何渲染事件监听
    },
    addMapLayer() {
      const projection = getProj('EPSG:3857');
      const projectionExtent = projection.getExtent();
      const size = getWidth(projectionExtent) / 256;
      const resolutions = new Array(19);
      const matrixIds = new Array(19);
      for (let z = 0; z < 19; ++z) {
        resolutions[z] = size / Math.pow(2, z);
        matrixIds[z] = z;
      }
      // 添加基础地图图层
      let tileGrid = new WMTSTileGrid({ origin: getTopLeft(projectionExtent), resolutions: resolutions, matrixIds: matrixIds });
      let baseMap = new Tile({ source: new WMTS({ url: this.MAP_OPTIONS[0].url, layer: this.MAP_OPTIONS[0].type, matrixSet: 'w', format: 'tiles', style: 'default', projection: 'EPSG:3857', tileGrid, wrapX: true }), className: 'map-deep', zIndex: 0 });
      this.map.addLayer(baseMap);
      //添加遮罩图层
      let url = 'https://t3.tianditu.gov.cn/cva_w/wmts?tk=24a30b7fae704dbf7d4c8cf6182e9f27';
      let tileGrid1 = new WMTSTileGrid({ origin: getTopLeft(projectionExtent), resolutions: resolutions, matrixIds: matrixIds });
      let markMap = new Tile({ source: new WMTS({ url, layer: 'cva', matrixSet: 'w', format: 'tiles', style: 'default', projection: 'EPSG:3857', tileGrid: tileGrid1, wrapX: true }), className: 'map', zIndex: 5 });
      this.map.addLayer(markMap);
    },
    //按省聚合
    addMarkByArea(infos) {
      infos.forEach(el => {
        let source = new VectorSource();
        el.lonlat.forEach(item => {
          let coordinates = fromLonLat([item.longitude, item.latitude]);
          let feature = new Feature({ geometry: new Point(coordinates), value: item });
          source.addFeature(feature);
        });
        let cluster = new Cluster({ source: source, distance: 100 });
        let layer = new Vector({
          source: cluster,
          className: el.layerName,
          id: 'cluster',
          zIndex: 6,
          style: feature => {
            let size = feature.get('features').length;
            if (size === 1) {
              let src = feature.values_.features[0].values_.value.status === 'WARNING' ? WarningIcon : NomalIcon;
              return new Style({
                image: new IconOl({ src: src, anchorOrigin: 'bottom-right', anchorXUnits: 'fraction', anchorYUnits: 'pixels', offsetOrigin: 'bottom-right' })
              });
            } else {
              let src = size > 10 ? Cluster1 : Cluster0;
              return new Style({
                image: new IconOl({ src: src }),
                text: new Text({ text: size.toString(), scale: 2, placement: 'point', offsetY: -18, fill: new Fill({ color: 'white' }) })
              });
            }
          }
        });
        this.map.addLayer(layer);
      });
    },
    //全部聚合
    addMarkByAll(deviceList) {
      let source = new VectorSource();
      deviceList.forEach(item => {
        let coordinates = fromLonLat([item.longitude, item.latitude]);
        let feature = new Feature({ geometry: new Point(coordinates), value: item });
        source.addFeature(feature);
      });
      let cluster = new Cluster({ source: source, distance: 100 });
      let layer = new Vector({
        source: cluster,
        className: 'cluster',
        id: 'cluster',
        zIndex: 6,
        style: feature => {
          let size = feature.get('features').length;
          if (size === 1) {
            let src = feature.values_.features[0].values_.value.status === 'WARNING' ? WarningIcon : NomalIcon;
            return new Style({
              image: new IconOl({ src: src, anchorOrigin: 'bottom-right', anchorXUnits: 'fraction', anchorYUnits: 'pixels', offsetOrigin: 'bottom-right' })
            });
          } else {
            let src = size > 10 ? Cluster1 : Cluster0;
            return new Style({
              image: new IconOl({ src: src }),
              text: new Text({ text: size.toString(), scale: 2, placement: 'point', offsetY: -18, fill: new Fill({ color: 'white' }) })
            });
          }
        }
      });
      this.map.addLayer(layer);
    },
    addMapOverlay() {
      //居中positioning(具体的值deepseek一问就出来了)，偏移offset
      this.deviceOverlay = new Overlay({ element: document.getElementById('deviceInfo'), offset: [0, -25], stopEvent: false, positioning: 'bottom-center' });
      this.map.addOverlay(this.deviceOverlay);
      // this.deviceOverlay.setPosition(fromLonLat([114.183456789, 30.287654321])); //此行别删，调试时会用到
    },
    mapClick(e) {
      let view = this.map.getView();
      let zoom = view.getZoom();
      let feature = this.map.forEachFeatureAtPixel(e.pixel, feat => feat);
      if (feature) {
        if (feature.values_.features.length > 1) {
          //是聚合图标时，进入下一层
          view.animate({ center: e.coordinate, zoom: zoom + 1 });
        } else {
          //非聚合图标，弹设备框
          this.curDeviceInfo = feature.values_?.features[0]?.values_?.value;
          this.curCoord = fromLonLat([this.curDeviceInfo.longitude, this.curDeviceInfo.latitude]);
          this.deviceOverlay.setPosition(this.curCoord);
          //先将设备坐标作为屏幕中心点，将地理坐标转成屏幕坐标，向上偏移pixels像素，再转成地理坐标后设置成地图中心点
          const pixels = 80;
          const pixel = this.map.getPixelFromCoordinate(this.curCoord);
          const offsetPixel = [pixel[0], pixel[1] - pixels];
          const newCenter = this.map.getCoordinateFromPixel(offsetPixel);
          view.animate({ center: newCenter, zoom }, { duration: 1000 });
          this.timer = setTimeout(() => {
            clearTimeout(this.timer);
            this.curCoord = null;
            this.deviceOverlay.setPosition(null);
          }, 8000);
        }
      } else {
        this.curCoord = null;
        console.log(111444, zoom, toLonLat(e.coordinate));
        clearTimeout(this.timer);
        this.deviceOverlay.setPosition(null);
      }
    },
    mapPointerMove(e) {
      let feature = this.map.forEachFeatureAtPixel(e.pixel, feat => feat);
      if (feature) {
        //根据feature.values_判断鼠标移入的内容是什么，feature.values_的值是new Feature时value的赋值
        console.log('鼠标移入', feature.values_);
      }
    },
    mapPostrender(e) {
      if (this.curCoord) {
        this.deviceOverlay.setPosition(this.curCoord);
      } else {
        clearTimeout(this.timer);
      }
    }
  }
};
</script>
<style lang="scss" scoped>
::v-deep {
  .ol-viewport {
    .ol-layers {
      .map-deep {
        canvas {
          filter: contrast(0.53) sepia(1) invert(1) brightness(1.2);
        }
      }
    }
    .ol-zoom {
      display: none;
    }
  }
  .deviceInfo {
    width: px(379);
    height: px(273);
    background: url('~@/assets/image/map/infoBg.png') no-repeat center;
    background-size: 100% 100%;
    background-color: rgba(13, 37, 64, 0.9);
    padding-left: px(17);
    padding-right: px(17);
    box-sizing: border-box;
    .titleBox {
      .title {
        background: linear-gradient(180deg, #4dddff 60%, #ffffff 0%);
        -webkit-background-clip: text;
        color: transparent;
      }
    }
    .infoBox {
      padding-left: px(17);
      box-sizing: border-box;
      background: url('~@/assets/image/map/infoItem.png') no-repeat center;
      background-size: 100% 100%;
    }
    .titleLabel {
      color: #80e6ff;
    }
    .titleContent {
      color: #ffffff;
    }
  }
}
</style>
